﻿using System;
/*
 Code Paragraph
 */
namespace ConsoleTest
{
    public class NetStreamTest
    {
        //服务器端口
        public static ushort port = 5000;

        #region 服务器同步处理客户端请求
        

        //同步方式模拟服务器处理客户端请求
        public static void ServerWaitForClient()
        {
            System.Net.IPAddress ipAddress = new System.Net.IPAddress(new byte[] { 127,0,0,1});

            System.Net.Sockets.TcpListener tcplistener = new System.Net.Sockets.TcpListener(ipAddress, port);

            tcplistener.Start();

            while (true)
            {
                try
                {
                    System.Console.WriteLine("Waiting for a client......");

                    //该方法引发服务器对客户端的等待，与客户段连接建立之后
                    //解除服务器的等待状态，进行处理；此处理方法为同步处理方式
                    System.Net.Sockets.TcpClient tcpclient = tcplistener.AcceptTcpClient();
                    System.Console.WriteLine("Connectiong Created .....");
                    ProcessClientRequest(tcpclient.GetStream());
                    System.Console.WriteLine("Client Disconnected.....");

                }
                catch (Exception e)
                {
                    System.Console.WriteLine(e.Message);
                }
            }
        }

        //同步方式处理客户端请求
        static void ProcessClientRequest(System.Net.Sockets.NetworkStream networkStream)
        {
            System.IO.StreamWriter sw = new System.IO.StreamWriter(networkStream);

            System.IO.StreamReader sr = new System.IO.StreamReader(@"kewin.txt", System.Text.Encoding.Default);

            string sTmp = sr.ReadLine();
            try
            {
                while (sTmp != null)
                {
                    System.Console.WriteLine("Sending :{0}",sTmp);

                    sw.WriteLine(sTmp);
                    sw.Flush();
                    sTmp = sr.ReadLine();
                }

            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.Message);
            }
            finally
            {
                sr.Close();
                sw.Close();
                networkStream.Close();
            }

        }
        #endregion 服务器同步处理客户端请求

        #region 服务器异步处理客户端请求
        /// <summary>
        /// 服务器异步处理客户端的主调方法
        /// </summary>
        public static void SerProcessClientAsync()
        {
            System.Net.IPAddress ipAddress = new System.Net.IPAddress(new byte[] { 127,0,0,1});
            System.Net.Sockets.TcpListener tcplistener= new System.Net.Sockets.TcpListener(ipAddress, port);
            tcplistener.Start();

            while (true)
            {
                try
                {
                    System.Console.WriteLine("Waiting for client ..........");
                    System.Net.Sockets.TcpClient tcpClient = tcplistener.AcceptTcpClient();
                    System.Console.WriteLine("Client Connected.....");
                    ClientRequestProcessing clientProc = new ClientRequestProcessing(tcpClient.GetStream());
                    clientProc.Go();
                }
                catch (Exception e)
                {
                    System.Console.WriteLine(e.Message);
                }
            }
        }
        /// <summary>
        /// 服务器客户端模式中，在服务器端一般都包含一个类,用该类的一个实例标识一个客户端请求
        /// </summary>
        class ClientRequestProcessing
        {
            /*
             由Go方法启动对客户端数据的读取；
             * 在回调方法中判断读取数据，如果读取数据则将返回的数据直接回发给
             * 回发完毕之后调用写结束的回调方法，在回调方法中又重新调用读方法；
             * 直到客户端不再向服务器发送数据；
             */
            static readonly int buffersize = 512;
            private byte[] m_Buffer;
            private System.Net.Sockets.NetworkStream m_NetWorkStream;
            private System.AsyncCallback m_CallBackRead;
            private System.AsyncCallback m_CallBackWrite;

            //构造函数
            public ClientRequestProcessing(System.Net.Sockets.NetworkStream networkStream)
            {
                m_NetWorkStream = networkStream;
                m_CallBackRead = new AsyncCallback(OnReadDone);
                m_CallBackWrite = new AsyncCallback(OnWriteDone);
                m_Buffer=new byte[buffersize];
            }
            /// <summary>
            /// 显示调用NetWorkStream写方法，启动对客户端的异步处理
            /// </summary>
            public void Go()
            {
                //异步方式读取客户端发送的数据
                m_NetWorkStream.BeginRead(m_Buffer, 0, m_Buffer.Length, m_CallBackRead, null);
            }

            /// <summary>
            ///NetWorkStream读取结束异步方法，方法内部调用NetWorkStream写方法
            /// </summary>
            /// <param name="asyncResult"></param>
            private void OnReadDone(System.IAsyncResult asyncResult)
            {
                //结束异步调用
                int nBytes = m_NetWorkStream.EndRead(asyncResult);

                if (nBytes > 0)
                {
                    string s = System.Text.Encoding.UTF8.GetString(m_Buffer, 0, nBytes);


                    System.Console.WriteLine("Async:{0} bytes received from client:{1}", nBytes, s);
                    //开始向流异步写入
                    m_NetWorkStream.BeginWrite(m_Buffer, 0, nBytes, m_CallBackWrite, null);
                }
                else
                {
                    //如果用户没有发送数据，则忽略客户端
                    System.Console.WriteLine("Async: Client request Processed.");
                    m_NetWorkStream.Close();
                    m_NetWorkStream = null;
                }
            }
            /// <summary>
            /// NetWorkStream写结束回调方法，方法内部调用Read方法
            /// </summary>
            /// <param name="asyncResult"></param>
            private void OnWriteDone(System.IAsyncResult asyncResult)
            {
                m_NetWorkStream.EndWrite(asyncResult);
                Console.WriteLine("Async : Write Done.");

                m_NetWorkStream.BeginRead(m_Buffer, 0, m_Buffer.Length, m_CallBackRead, null);
            }
        }

        #endregion 服务器异步处理客户端请求

        #region 获取网络接口和网络状态信息
        /// <summary>
        /// 发现可用的网络接口
        /// </summary>
        public static void GetNetWorkInterface()
        {
            //获取机器上的所有可用网络接口
            System.Net.NetworkInformation.NetworkInterface[] nis = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();

            foreach (System.Net.NetworkInformation.NetworkInterface ni in nis)
            {
                System.Console.WriteLine("Name:"+ni.Name);
                System.Console.WriteLine("Description:" + ni.Description);
                System.Console.WriteLine("Status:" + ni.OperationalStatus.ToString());
                System.Console.WriteLine("Speed{0}Kb:" + ni.Speed/1024);
                System.Console.WriteLine("Media Acess Control(MAC):" + ni.GetPhysicalAddress().ToString());
                System.Console.WriteLine("---------------------------------------------------------");
            }
        }
        /// <summary>
        /// 用来测定远程机器是否可以通过网络进行访问
        /// </summary>
        public static void Ping()
        {
            using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
            {
                System.Net.NetworkInformation.PingReply rep = ping.Send("www.sina.com", 10000);
                System.Console.WriteLine("IP:{0} Status:{1}",rep.Address,rep.Status);
            }
        }
        #endregion 获取网络接口和网络状态信息

        #region 其他网络类库
        public static void WebClient()
        {
            /*
             * System.Net.FileWebRequest/System.Net.FtpWebRequest/System.Net.HttpWebRequest
             * 类允许使用对应的协议完成请求；获得这些类的实例一般推荐使用System.Net.WebRequest的Create方法
             */

            System.Net.WebClient webclient = new System.Net.WebClient();
            //获得ftpWebRequest的实例一般都是用WebRequest的静态方法
            System.Net.FtpWebRequest ftpReq = System.Net.WebRequest.Create("ftp://172.16.1.101/编程软件/Php/DzSoft-PHP-Editor/DzSoft PHP Editor 4.2.2.8.zip") as System.Net.FtpWebRequest;
            ftpReq.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;
            
            ftpReq.Credentials = new System.Net.NetworkCredential("  ", " ");
            System.Net.FtpWebResponse ftrRep = ftpReq.GetResponse() as System.Net.FtpWebResponse;
            System.IO.StreamReader sr = new System.IO.StreamReader(ftrRep.GetResponseStream(), System.Text.Encoding.UTF8);
            System.Console.WriteLine(sr.ReadToEnd());
            sr.Close();


            //byte[] bytes= webclient.DownloadData("ftp://172.16.1.101/编程软件/Php/DzSoft-PHP-Editor/DzSoft PHP Editor 4.2.2.8.zip");
            //System.IO.File.WriteAllBytes("down.zip", bytes);
        }
        #endregion 其他网络类库

        #region HTTP.SYS的使用
        /// <summary>
        /// 通过HTTPSYS实现自定义的web请求处理器
        /// </summary>
        public static void HttpSYS()
        {
            //每次客户端向服务器发送 http://localhost:8008/hello/ 请求，服务器返回一个页面
            System.Net.HttpListener httplistener = new System.Net.HttpListener();
            string uri = string.Format("http://localhost:8008/hello/");
            httplistener.Prefixes.Add(uri);
            httplistener.Start();

            while (true)
            {

                System.Net.HttpListenerContext ctx = httplistener.GetContext();
                ctx.Response.ContentType = "text/html";
                System.IO.TextWriter writer = new System.IO.StreamWriter(ctx.Response.OutputStream
                    , System.Text.Encoding.Unicode);


                //str 暂时存放一个web页面的源码，利用writer将页面输出
                string str = System.IO.File.ReadAllText("HTML.txt", System.Text.Encoding.Default);
                //writer.WriteLine("<html><body><b>Page asked at{0}</b><br>URL:{1}</body></html>",System.DateTime.Now,ctx.Request.Url);
                writer.Write(str);

                

                writer.Flush();
                writer.Close();
            }

        }
        /// <summary>
        /// 异步方式处理HTTP请求
        /// </summary>
        public static void HTTPSYSAsync()
        {
            //每次客户端向服务器发送 http://localhost:8008/hello/ 请求，服务器返回一个页面
            System.Net.HttpListener httplistener = new System.Net.HttpListener();
            string uri = string.Format("http://localhost:8008/hello/");
            httplistener.Prefixes.Add(uri);
            httplistener.Start();

            while (true)
            {
                System.IAsyncResult result = httplistener.BeginGetContext(ProcessHTTPResponse, httplistener);
                System.Threading.Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// 异步处理回调方法
        /// </summary>
        /// <param name="asyncResult"></param>
        static void ProcessHTTPResponse(System.IAsyncResult asyncResult)
        {
            System.Net.HttpListener httplistener = asyncResult.AsyncState as System.Net.HttpListener;
            System.Net.HttpListenerContext ctx = httplistener.EndGetContext(asyncResult);
            ctx.Response.ContentType = "text/html";
            System.IO.TextWriter writer = new System.IO.StreamWriter(ctx.Response.OutputStream, System.Text.Encoding.Unicode);
            //str 暂时存放一个web页面的源码，利用writer将页面输出
            string str = System.IO.File.ReadAllText("HTML.txt", System.Text.Encoding.Default);
            //writer.WriteLine("<html><body><b>Page asked at{0}</b><br>URL:{1}</body></html>",System.DateTime.Now,ctx.Request.Url);
            writer.Write(str);
            writer.Flush();
            writer.Close();
        }
        #endregion HTTP.SYS的使用

        #region 邮件发送
        /// <summary>
        /// 演示右键发送
        /// </summary>
        public static void SmtpClient()
        {
            /*
             * System.Web.Mail 命名空间下的类已经被废弃了，如果发送邮件
             * 必须使用System.Net.Mail命名空间
             */

            System.Net.Mail.SmtpClient client =new System.Net.Mail.SmtpClient("smtp.163.com",25);
            client.Credentials = new System.Net.NetworkCredential("yansanhu@163.com", "1qaz2wsx3edc@42@");
            System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage("yansanhu@163.com", "yansanhu@qq.com", "smtp test", "my body");
            msg.Attachments.Add(new System.Net.Mail.Attachment("kewin.txt"));
            client.Send(msg);
        }
        #endregion 右键发送
    }
}

